package com.booksystem.campuslibrarymanagementsystem.controller.admin;

import com.booksystem.campuslibrarymanagementsystem.commen.request.adminrequest.AccountManagement.*;
import com.booksystem.campuslibrarymanagementsystem.commen.result.Result;
import com.booksystem.campuslibrarymanagementsystem.commen.result.Verifys;
import com.booksystem.campuslibrarymanagementsystem.commen.result.adminresult.AccountManagememtR.ActlistR;
import com.booksystem.campuslibrarymanagementsystem.commen.result.adminresult.AccountManagememtR.AuditlistR;
import com.booksystem.campuslibrarymanagementsystem.commen.result.adminresult.AccountManagememtR.SelectActList;
import com.booksystem.campuslibrarymanagementsystem.entity.AccountTable;
import com.booksystem.campuslibrarymanagementsystem.entity.UserTable;
import com.booksystem.campuslibrarymanagementsystem.service.AccountTableService;
import com.booksystem.campuslibrarymanagementsystem.service.UserTableService;
import com.booksystem.campuslibrarymanagementsystem.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/Admin")
@Api(tags = "账户管理")
public class AccountManagementController {
private final String idt = "admin";
    Verifys verifys = new Verifys();
    UserTable userTable = new UserTable();
    AccountTable accountTable = new AccountTable();
    @Autowired
    private AccountTableService accountTableService;

    @Autowired
    private UserTableService userTableService;

    /**
     * 1.审核列表接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody addaccount
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：在account数据表中查询所有状态为未通过的账户并保存到list中并判断list是否有数据。
     * 6.没有数据：返回失败信息-没有待审核的账户。有数据：将list返回到前端。
     */
    @PostMapping("/auditAccountList")
    @ApiOperation(value = "审核列表", notes = "审核提交的账户信息")
    public Result<List<AuditlistR>> auditAccountList(@RequestBody Auditlist auditlist) {
        verifys = AuditUtil.verifyUtil(auditlist.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                List<AccountTable> list = accountTableService.queryByState("未通过");
                if (list.isEmpty()) {
                    return Result.fail("没有待审核的账户");
                } else {
                    ArrayList<AuditlistR> list1 = new ArrayList<>();
                    for (int i = 0; i < list.size(); i++) {
                        AccountTable accountTable1 = list.get(i);
                        AuditlistR auditlistR = new AuditlistR();
                        auditlistR.setAccount(accountTable1.getAccount());
                        auditlistR.setName(accountTable1.getName());
                        auditlistR.setEmail(accountTable1.getEmail());
                        auditlistR.setId(accountTable1.getId());
                        auditlistR.setIdentity(accountTable1.getIdentity());
                        auditlistR.setState(accountTable1.getState());
                        list1.add(auditlistR);
                    }
                    System.out.println("审核列表完成");
                    return Result.success(list1, list1.size());
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }

    /**
     * 2.审核账户接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody AuditAct（token，account账户）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：通过要审批的学号在user表内查询是否存在。
     * 6.不存在：返回失败信息-该学号在user表内不存在。存在：查看此学号在user表内的状态。
     * 7.启动:返回失败信息-该学号的状态已启动，请勿重复审批。未启动：获取随机salt并和用户输入的密码合并，通过哈希加密后得到加密密码，和sale一起更新到account账户中，并更新此账户在user表，account表的状态为启动，通过。
     */
    @PostMapping("/auditAccount")
    @ApiOperation(value = "审核账户", notes = "审核提交的账户信息")
    public Result auditAccount(@RequestBody Auditact auditact) {
        verifys = AuditUtil.verifyUtil(auditact.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                accountTable = verifys.getAccountTable();
                int ids = Integer.parseInt(auditact.getAccount());
                UserTable userTable = userTableService.queryByIds(ids);
                if (userTable != null) {
                    switch (userTable.getState()){
                       case "未启动":
                           String salt = SaltUtil.saltGet();
                           String psw = accountTable.getPassword() + salt;
                           String generatedHash = HashUtil.HashGet(psw);
                           boolean a = accountTableService.upDataPswAndSaltAndState(auditact.getAccount(), generatedHash, salt, "已通过");
                           if (a) {
                               EmailSender.sendEmails(accountTable.getEmail(), "【校园图书管理系统】提示：" + userTable.getName() + " 同学你好，你的账户" + auditact.getAccount() + "于：" + TimeUtil.getTime() + "审批通过。");
                               userTableService.upDataState(auditact.getAccount(), "已通过");
                               System.out.println("审核账户完成：" + userTable.getName());
                               return Result.success("账户已通过", 1);
                           } else {
                               return Result.fail("该账户审批失败。");
                           }
                        case "已通过":
                            return Result.fail("该学号的状态已启动，请勿重复审批");
                        case "已停用":
                            return Result.fail("该学号的状态已被停用");
                        default:
                            return Result.fail("该学号的状态异常");
                    }
                } else {
                    return Result.fail("该学号在user表内不存在");
                }
            default:
                return Result.fail(verifys.getMsg());
        }


    }

    /**
     * 3.权限管理接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody Idtup（token，account账户，identity身份）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：判断输入的学号是否格式正确。
     * 6.不正确：返回失败信息-学号格式错误。正确：通过输入的学号在account表内查询是否存在。
     * 7.不存在：返回失败信息-要升级的学号不存在。存在：判断该账户状态
     * 8.未通过：返回失败信息-要升级的学号未被审核通过，请先为此账户审核。已停用：返回错误信息-该学号已停用。已通过：判断要更改的身份和以前的身份是否一致。
     * 9.一致；返回失败信息-"此账户权限已为：" + idtup.getIdentity()。不一致：判断输入的身份拼写是否正确。
     * 10.不正确：返回失败信息-身份码必须写为user，approval，admin。。正确：在account表中进行身份更新，并发送邮件到该账户的邮箱中。
     */
    @PostMapping("/identityUpdate")
    @ApiOperation(value = "权限管理", notes = "可以为user用户进行权限升级进行基础信息注册")
    public Result identityUpdate(@RequestBody Idtup idtup) {
        verifys = AuditUtil.verifyUtil(idtup.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                if (idtup.getAccount().matches("^\\d{9}$")) {
                    AccountTable accountTable1 = accountTableService.queryByAccount(idtup.getAccount());
                    if (accountTable1 != null) {
                        String state = accountTable1.getState();
                        switch (state) {
                            case "已通过":
                                if (!accountTable1.getIdentity().equals(idtup.getIdentity())) {
                                    String identity = idtup.getIdentity();
                                    if ("user".equals(identity) || "approval".equals(identity) || "admin".equals(identity)) {
                                        boolean a = accountTableService.upDataIdentity(idtup.getAccount(), idtup.getIdentity());
                                        if (a) {
                                            EmailSender.sendEmails(accountTable1.getEmail(), "【校园图书管理系统】提示：您的账户" + idtup.getAccount() + "权限已升级为" + idtup.getIdentity());
                                            System.out.println("账户"+ accountTable1.getAccount() + "权限更新成功");
                                            return Result.success("该账户权限已更新为" + idtup.getIdentity(), 1);
                                        } else {
                                            return Result.fail("权限升级失败");
                                        }
                                    } else {
                                        return Result.fail("身份码必须写为user，approval，admin。");
                                    }
                                } else {
                                    return Result.fail("此账户权限已为：" + idtup.getIdentity());
                                }
                            case "未通过":
                                return Result.fail("要升级的学号未被审核通过，请先为此账户审核");
                            case "已停用":
                                return Result.fail("该学号已停用");
                            default:
                                return Result.fail("该学号状态异常");
                        }
                    } else {
                        return Result.fail("要升级的学号不存在");
                    }
                } else {
                    return Result.fail("学号格式错误");
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }


    /**
     * 4.账户列表接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody Actlist（token）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：在account表内查询到所有状态为已通过的账户，并保存到list中并判断是否为空
     * 6.list为空：返回失败信息-暂时没有通过的账户。list不为空：通过for循环将list保存到list1中
     * 7.返回成功数据-list1
     */
    @PostMapping("/accountList")
    @ApiOperation(value = "账户列表", notes = "自动获取所有通过的账户")
    public Result<List<ActlistR>> accountList(@RequestBody Actlist actlist) {
        verifys = AuditUtil.verifyUtil(actlist.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                List<AccountTable> list = accountTableService.list();
                if (list.isEmpty()) {
                    return Result.fail("暂时没有通过的账户");
                } else {
                    ArrayList<ActlistR> list1 = new ArrayList<>();
                    for (int i = 0; i < list.size(); i++) {
                        AccountTable accountTable1 = list.get(i);
                        if (!accountTable1.getState().equals("未通过")) {
                            ActlistR actlistR = new ActlistR();
                            actlistR.setAccount(accountTable1.getAccount());
                            actlistR.setName(accountTable1.getName());
                            actlistR.setEmail(accountTable1.getEmail());
                            actlistR.setId(accountTable1.getId());
                            actlistR.setIdentity(accountTable1.getIdentity());
                            actlistR.setState(accountTable1.getState());
                            list1.add(actlistR);
                        } else {
                            continue;
                        }

                    }
                    System.out.println("列表发送成功");
                    return Result.success(list1, list1.size());
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }

    /**
     * 5.查询账户列表接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody Accountlist（token，account学号，name名字，identity身份，state状态）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：判断输入的account格式是否正确或为空
     * 6.判断不通过：返回失败信息-account格式不为学号格式。判断通过：判断输入的身份是否正确或为空
     * 7.判断不通过：identity身份异常。判断通过：从account表内查询所有符合的信息并保存到list中判断是否为空。
     * 8.为空：返回失败信息-暂时没有数据。不为空：将list数据保存到list1中
     * 9.返回成功数据-list1
     */
    @PostMapping("/selectAccountList")
    @ApiOperation(value = "查询账户列表", notes = "动态查询账户（学号，名字，身份，状态）")
    public Result<List<SelectActList>> selectAccountList(@RequestBody Accountlist accountlist) {
        verifys = AuditUtil.verifyUtil(accountlist.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                String account1 = accountlist.getAccount();
                if (account1.matches("^\\d{9}$") || account1.isEmpty()) {
                    String state = accountlist.getState();
                    if (state.isEmpty() || "已通过".equals(state) || "未通过".equals(state) || "已停用".equals(state)) {
                        String identity1 = accountlist.getIdentity();
                        if (identity1.isEmpty() || "admin".equals(identity1) || "approval".equals(identity1) || "user".equals(identity1)) {
                            if (accountlist.getXuahao() == 1 || accountlist.getXuahao() == 2) {
                                List<AccountTable> list = accountTableService.selectListAccount(account1, accountlist.getName(), identity1, state);
                                if (!list.isEmpty()) {
                                    ArrayList<SelectActList> list1 = new ArrayList<>();
                                    for (int i = 0; i < list.size(); i++) {
                                        if (accountlist.getXuahao() == 1) {
                                            AccountTable accountTable1 = list.get(i);
                                            if ("已通过".equals(accountTable1.getState()) || "已停用".equals(accountTable1.getState())) {
                                                updatesList(accountTable1,list1);
                                            }
                                        } else if (accountlist.getXuahao() == 2) {
                                            AccountTable accountTable1 = list.get(i);
                                            if ("未通过".equals(accountTable1.getState())) {
                                                updatesList(accountTable1,list1);
                                            }
                                        } else {
                                            continue;
                                        }
                                    }
                                    System.out.println("查询成功");
                                    return Result.success(list1, list1.size());
                                } else {
                                    return Result.fail("暂时没有数据");
                                }
                            } else {
                                return Result.fail("请选择1or2");
                            }
                        } else {
                            return Result.fail("identity身份异常");
                        }
                    } else {
                        return Result.fail("state状态异常");
                    }
                } else {
                    return Result.fail("account格式不为学号格式");
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }
    public void updatesList(AccountTable accountTable1,ArrayList<SelectActList> list1){
        SelectActList selectActList = new SelectActList();
        selectActList.setAccount(accountTable1.getAccount());
        selectActList.setName(accountTable1.getName());
        selectActList.setEmail(accountTable1.getEmail());
        selectActList.setId(accountTable1.getId());
        selectActList.setIdentity(accountTable1.getIdentity());
        selectActList.setState(accountTable1.getState());
        list1.add(selectActList);
    }


    /**
     * 5.状态更新接口。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody Updateaccountstate（token，account）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：判断输入的ids格式是否正确。
     * 6.不正确：返回失败信息-ids格式不为学号格式。正确：通过输入的ids在user表内查询是否存在。
     * 7.不存在：返回失败信息-该学号在user表内不存在。存在；判断该账户的状态是否为未启动
     * 8.是：返回失败信息-该账户未启动，状态无法更改。不是：通过输入的ids更新状态，并判断是否更新成功
     * 9.更新失败：返回失败信息-状态停用/启动失败。更新成功：通过ids到account表内更新此账户的状态。并判断是否更新成功
     * 10.更新失败：返回失败信息-停用/启动失败。更新成功：发送邮件到此账户的邮箱上并返回成功信息-账户停用/启动成功
     */
    @PostMapping("/updateAccountState")
    @ApiOperation(value = "状态更新", notes = "可以为admin，approval，user进行基础信息注册")
    public Result updateAccountState(@RequestBody Updateaccountstate updateaccountstate) {
        verifys = AuditUtil.verifyUtil(updateaccountstate.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                if (!updateaccountstate.getAccount().matches("^\\d{9}$")) {
                    return Result.fail("IDs格式不为学号格式");
                }
                int ids = Integer.parseInt(updateaccountstate.getAccount());
                UserTable userTable = userTableService.queryByIds(ids);

                if (userTable == null) {
                    return Result.fail("在user表内没有找到此账户");
                }
                switch (userTable.getState()) {
                    case "已通过":
                        return handleStateChange(updateaccountstate, "已停用", "账户停用成功", "账户停用失败", "账户已被停用");

                    case "已停用":
                        return handleStateChange(updateaccountstate, "已通过", "账户启动成功", "账户启动失败", "账户已被启动");
                    default:
                        return Result.fail("该账户未启动，状态无法更改");
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }
    private Result handleStateChange(Updateaccountstate updateaccountstate, String newState, String successMsg, String failMsg, String emailMsg) {
        boolean updatedUserTable = userTableService.upDataState(updateaccountstate.getAccount(), newState);
        if (updatedUserTable) {
            boolean updatedAccountTable = accountTableService.upDataState(updateaccountstate.getAccount(), newState);
            if (updatedAccountTable) {
                AccountTable accountTable = accountTableService.queryByAccount(updateaccountstate.getAccount());
                EmailSender.sendEmails(accountTable.getEmail(), "【校园图书管理系统】提示：" + emailMsg);
                System.out.println(updateaccountstate.getAccount() + "  状态更新成功");
                return Result.success(successMsg, 1);
            } else {
                return Result.fail(failMsg);
            }
        } else {
            return Result.fail(failMsg);
        }
    }


    /**
     * 6.查看账户。
     *
     * @return Result.success();or return Result.fail();
     * @RequestBody Actlist（token）
     * 1.解析获得的token值，并保存到键值对Map-parsed中
     * 2.判断parsed是否为null
     * 3.null：返回失败信息-请输入正确token值。不为null：判断解析到的身份码是否为admin。
     * 4.不为admin；返回失败信息-身份权限不足。是admin：判断解析到的学号是否在account表中存在。
     * 5.不存在：返回失败信息-该学号不存在。存在：将解析获取查询到的account进行发送至后端
     */
    @PostMapping("/myAccount")
    @ApiOperation(value = "查看账户", notes = "查看个人账户")
    public Result myAccount(@RequestBody Actlist actlist) {
        verifys = AuditUtil.verifyUtil(actlist.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                System.out.println("账户信息已发送");
                return Result.success(verifys.getAccountTable(), 1);
            default:
                return Result.fail(verifys.getMsg());

        }
    }

    /***
     * 修改账户信息
     * @param updateaccount
     * @return
     */
    @PostMapping("/updataAccount")
    @ApiOperation(value = "修改账户", notes = "修改账户-名字-邮箱")
    public Result updataAccount(@RequestBody Updateaccount updateaccount) {
        verifys = AuditUtil.verifyUtil(updateaccount.getToken(),idt,accountTableService);
        switch (verifys.getMsg()) {
            case "成功":
                String acout = verifys.getAccountTable().getAccount();
                if (!updateaccount.getName().isEmpty() && !updateaccount.getEmail().isEmpty()) {
                    if (updateaccount.getEmail().matches("^[1-9]\\d{0,9}@qq\\.com$")) {
                        if (!updateaccount.getEmail().equals(verifys.getAccountTable().getEmail())) {
                            EmailSender.sendEmails(updateaccount.getEmail(), "【校园图书管理系统】，您的邮箱地址已从" + accountTable.getEmail() + "更新至" + updateaccount.getEmail() +
                                    "来自账户：" + acout);
                        }
                        userTableService.upDataName(acout, updateaccount.getName());
                        boolean a = accountTableService.upDataEmailAndName(acout, updateaccount.getEmail(), updateaccount.getName());
                        if (a) {
                            System.out.println( updateaccount.getName() +"账户信息修改成功");
                            return Result.success("更新成功", 1);
                        } else {
                            return Result.fail("更新失败！");
                        }
                    } else {
                        return Result.fail("邮箱格式错误，并且仅支持QQ邮箱（@qq.com）！");
                    }
                } else {
                    return Result.fail("信息填写不完整！");
                }
            default:
                return Result.fail(verifys.getMsg());
        }
    }


}
